﻿/* 2013/6/27 */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Cosmos.Media
{
    class ID3V2Header
    {
        public const int TotalLength = 10;
        public const int HeaderLength = 3;
        public const int SizeLength = 4;

        private static readonly byte[] AvailableHeader =
            new byte[] { (byte)'I', (byte)'D', (byte)'3' };

        public byte[] Header
        {
            get;
            private set;
        }

        public byte Ver
        {
            get;
            set;
        }

        public byte Revision
        {
            get;
            set;
        }

        public byte Flag
        {
            get;
            set;
        }

        public byte[] Size
        {
            get;
            private set;
        }

        public int AllFrameSize
        {
            get
            {
                int allFrameSize
                    = (Size[0] & 0x7F) * 0x200000
                    + (Size[1] & 0x7F) * 0x400
                    + (Size[2] & 0x7F) * 0x80
                    + (Size[3] & 0x7F);
                return allFrameSize;
            }
        }

        public ID3V2Header()
        {
            Header = new byte[HeaderLength];
            Size = new byte[SizeLength];
        }

        /// <summary> 
        /// Loads ID3V2 tag header information from a byte array.
        /// </summary> 
        /// <param name = "bytes">Bytes of ID3V2 tag header, which are extracted from head of file.</param>
        public void Load(byte[] bytes)
        {
            int i;
            int j;
            int position = 0;
            int currentIndex = 0;

            // Extracts header.
            for (i = currentIndex, j = 0; i < currentIndex + ID3V2Header.HeaderLength;
                i++, j++)
            {
                Header[j] = bytes[i];
                position++;
            }
            currentIndex = position;

            // Extracts ver bit.
            Ver = bytes[++position];

            // Extracts revision bit.
            Revision = bytes[++position];

            // Extracts flag bit.
            Flag = bytes[++position];

            // Extracts size.
            for (i = currentIndex, j = 0; i < currentIndex + ID3V2Header.SizeLength;
                i++, j++)
            {
                Size[j] = bytes[i];
                position++;
            }
            currentIndex = position;
        }

        public bool isAvailable
        {
            get
            {
                return Header.SequenceEqual(AvailableHeader);
            }
        }
    }
}
